<?php
# 文件名称:mysql.php
# MetInfo在线反馈系统 
# Copyright (C) 长沙米拓信息技术有限公司 (http://www.metinfo.cn). All rights reserved.
defined( '_SYS' ) or die( 'No direct script access allowed' );

class C_mysql
{
	var $name			= 'mysql';
	var $_sql			= '';
	
	var $_nullDate		= '0000-00-00 00:00:00';
	var $_nameQuote		= '`';	
	
	var $_quoted		= null;
	
	var $_hasQuoted		= null;
	var $_errorNum		= 0;
	
	var $_errorMsg		= '';
	
	var $_table_prefix	= '';
	
	var $_resource		= '';
	
	var $_limit			= 0;
	
	var $_offset		= 0;
	
	var $_cursor		= null; //最后查询资源
	
	var $dbsession		= null;
	
	function C_mysql( $options )
	{
		// 在PHP4中注册一个伪造的析构函数__destruct
		if (version_compare(PHP_VERSION, '5') == -1) {
			register_shutdown_function((array(&$this, '__destruct')));
		}
		
		$host						= array_key_exists('host', $options)	? $options['host']		: 'localhost';
		$user						= array_key_exists('user', $options)	? $options['user']		: '';
		$password					= array_key_exists('password',$options)	? $options['password']	: '';
		$database					= array_key_exists('database',$options)	? $options['database']	: '';
		$this->_table_prefix		= array_key_exists('prefix', $options)	? $options['prefix']	: 'met_';
		$select						= array_key_exists('select', $options)	? $options['select']	: true;
		$this->dbsession = $options;
		if (!function_exists( 'mysql_connect' )) {
			$this->_errorNum = 1;
			$this->_errorMsg = 'The MySQL adapter "mysql" is not available.';
			return;
		}
		
		// 连接数据库服务器
		if (!($this->_resource = @mysql_connect( $host, $user, $password, true ))) {
			$this->_errorNum = 2;
			$this->_errorMsg = 'Could not connect to MySQL';			
			return;
		}
		if($this->getVersion() > '4.1') {
			@mysql_query("SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary", $this->_resource);
		}
		$this->setUTF();
		
		if ( $select ) {
			$this->select($database);
		}
	}
	function __destruct()
	{
		//session_write调用close()
	}
	function close()
	{
		$return = false;
		if (is_resource($this->_resource)) {
			$return = mysql_close($this->_resource);
		}
		//var_dump('mysql closed');
		return $return;
	}
		
	// 检查连接是否可用
	function connected()
	{
		if(is_resource($this->_resource)) {
			return mysql_ping($this->_resource);
		}
		return false;
	}
	// 选择数据库
	function select($database)
	{
		if ( ! $database )
		{
			return false;
		}
		
		if ( !mysql_select_db( $database, $this->_resource )) {
			$this->_errorNum = 3;
			$this->_errorMsg = 'Could not connect to database';
			return false;
		}
		
		// 绕过 mysql 5 的缺陷
		if ( strpos( $this->getVersion(), '5' ) === 0 ) {
			$this->setQuery( "SET sql_mode = ''" );
			$this->query();
		}
		return true;
	}
	function setQuery( $sql, $offset = 0, $limit = 0 )
	{
		$this->_sql		= $sql;
		$this->_limit	= (int) $limit;
		$this->_offset	= (int) $offset;
	}
	
	// 判断是否支持UTF
	function hasUTF()
	{
		$verParts = explode( '.', $this->getVersion() );
		return ($verParts[0] == 5 || ($verParts[0] == 4 && $verParts[1] == 1 && (int)$verParts[2] >= 2));
	}
	//设置字符集
	function setUTF()
	{
		mysql_query( "SET NAMES 'utf8'", $this->_resource );
	}
	//执行查询
	function query()
	{
		if (!is_resource($this->_resource)) {
			return false;
		}
		$sql = $this->_sql;
		if ($this->_limit > 0 || $this->_offset > 0) {
			$sql .= ' LIMIT '.$this->_offset.', '.$this->_limit;
		}
		$this->_errorNum = 0;
		$this->_errorMsg = '';		
		$this->_cursor = mysql_query( $sql, $this->_resource );		
		if (!$this->_cursor)
		{
			$this->_errorNum = mysql_errno( $this->_resource );
			$this->_errorMsg = mysql_error( $this->_resource )." SQL=$sql";
			return false;
		}
		return $this->_cursor;
	}
/*
	function getOne( $query )
	{
		$this->setQuery( $query );
		if (!($cur = $this->query())) {
			return null;
		}
		$row = mysql_fetch_assoc( $cur );
		mysql_free_result( $cur );
		return $row;
	}*/
	
	//影响行数
	function getAffectedRows()
	{
		return mysql_affected_rows( $this->_resource );
	}
	//记录数
	function getNumRows( $cur=null )
	{
		return mysql_num_rows( $cur ? $cur : $this->_cursor );
	}
	function getNumFields($cur=null) 
	{
		return mysql_num_fields( $cur ? $cur : $this->_cursor );
	}
	//加载第一条记录第一列结果
	function loadResult()
	{
		if (!($cur = $this->query())) {
			return null;
		}		
		$ret = null;		
		if ($row = mysql_fetch_row( $cur )) {
			$ret = $row[0];
		}
		mysql_free_result( $cur );
		return $ret;
	}
	function GetOne( $query )
	{
		$this->setQuery( $query );
		$result = $this->loadResult();
		return $result;
	}
	//数组形式
	function loadResultArray($numinarray = 0)
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$array = array();
		while ($row = mysql_fetch_row( $cur )) {
			$array[] = $row[$numinarray];
		}
		mysql_free_result( $cur );
		return $array;
	}
	//关联数组
	function loadAssoc()
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$ret = null;		
		if ($array = mysql_fetch_assoc( $cur )) {
			$ret = $array;
		}
		mysql_free_result( $cur );
		return $ret;
	}
	// 链表
	function loadAssocList( $key='' )
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$array = array();
		while ($row = mysql_fetch_assoc( $cur )) {
			if ($key) {
				$array[$row[$key]] = $row;
			} else {
				$array[] = $row;
			}
		}
		mysql_free_result( $cur );
		return $array;
	}
	// 对象
	function loadObject( )
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$ret = null;
		if ($object = mysql_fetch_object( $cur )) {
			$ret = $object;
		}
		mysql_free_result( $cur );
		return $ret;
	}
	// 对象链
	function loadObjectList( $key='' )
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$array = array();
		while ($row = mysql_fetch_object( $cur )) {
			if ($key) {
				$array[$row->$key] = $row;
			} else {
				$array[] = $row;
			}
		}
		mysql_free_result( $cur );
		return $array;
	}
	function loadRow()
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$ret = null;
		if ($row = mysql_fetch_row( $cur )) {
			$ret = $row;
		}
		mysql_free_result( $cur );
		return $ret;
	}
	function loadRow_s($cur=null)
	{
		if (!$cur) {
			return null;
		}
		$ret = null;
		if ($row = mysql_fetch_row( $cur )) {
			$ret = $row;
		}		
		return $ret;
	}
	function loadRowList( $key=null )
	{
		if (!($cur = $this->query())) {
			return null;
		}
		$array = array();
		while ($row = mysql_fetch_row( $cur )) {
			if ($key !== null) {
				$array[$row[$key]] = $row;
			} else {
				$array[] = $row;
			}
		}
		mysql_free_result( $cur );
		return $array;
	}
	
	function getErrorNum() {
		return $this->_errorNum;
	}

	function getErrorMsg($escaped = false)
	{
		if($escaped) {
			return addslashes($this->_errorMsg);
		} else {
			return $this->_errorMsg;
		}
	}
	function getPrefix()
	{
		return $this->_table_prefix;
	}
	
	//以对象的方式写入数据表
	function insertObject( $table, &$object, $keyName = NULL )
	{
		$fmtsql = 'INSERT INTO '.$this->nameQuote($table).' ( %s ) VALUES ( %s ) ';
		$fields = array();
		foreach (get_object_vars( $object ) as $k => $v) {
			if (is_array($v) or is_object($v) or $v === NULL) {
				continue;
			}
			if ($k[0] == '_') { // 内部变量
				continue;
			}
			$fields[] = $this->nameQuote( $k );
			$values[] = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v;
		}
		$this->setQuery( sprintf( $fmtsql, implode( ",", $fields ) ,  implode( ",", $values ) ) );
		if (!$this->query()) {
			return false;
		}
		$id = $this->insertid();
		if ($keyName && $id) {
			$object->$keyName = $id;
		}
		return true;
	}
	//更新
	function updateObject( $table, &$object, $keyName, $updateNulls=true )
	{
		$fmtsql = 'UPDATE '.$this->nameQuote($table).' SET %s WHERE %s';
		$tmp = array();
		foreach (get_object_vars( $object ) as $k => $v)
		{
			if( is_array($v) or is_object($v) or $k[0] == '_' ) { // 内部变量或其它非字段变量
				continue;
			}
			if( $k == $keyName ) { // 主键
				$where = $keyName . '=' . $this->Quote( $v );
				continue;
			}
			if ($v === null)
			{
				if ($updateNulls) {
					$val = 'NULL';
				} else {
					continue;
				}
			} else {
				$val = $this->isQuoted( $k ) ? $this->Quote( $v ) : (int) $v;
			}
			$tmp[] = $this->nameQuote( $k ) . '=' . $val;
		}
		$this->setQuery( sprintf( $fmtsql, implode( ",", $tmp ) , $where ) );
		return $this->query();
	}
	function insertid()
	{
		return mysql_insert_id( $this->_resource );
	}
	function getVersion()
	{
		return mysql_get_server_info( $this->_resource );
	}
	// 获取所有数据表
	function getTableList()
	{
		$this->setQuery( 'SHOW TABLES' );
		if (!($cur = $this->query())) {
			return null;
		}
		$array = array();
		while ($row = mysql_fetch_row( $cur )) 
		{
			if(strstr($row[0],$this->_table_prefix) != false)
			{
				$array[] = $row[0];
			}
		}
		mysql_free_result( $cur );
		return $array;
	}
	function getTableCreate( $tables )
	{
		settype($tables, 'array'); //强制为数组格式
		$result = array();
		foreach ($tables as $tblval) {
			$this->setQuery( 'SHOW CREATE table ' . $this->getEscaped( $tblval ) );
			$rows = $this->loadRowList();
			foreach ($rows as $row) {
				$result[$tblval] = $row[1];
			}
		}
		return $result;
	}
	// 表字段
	function getTableFields( $tables, $typeonly = true )
	{
		settype($tables, 'array'); //强制为数组格式
		$result = array();
		foreach ($tables as $tblval)
		{
			$this->setQuery( 'SHOW FIELDS FROM ' . $tblval );
			$fields = $this->loadObjectList();
			if($typeonly)
			{
				foreach ($fields as $field) {
					$result[$tblval][$field->Field] = preg_replace("/[(0-9)]/",'', $field->Type );
				}
			}
			else
			{
				foreach ($fields as $field) {
					$result[$tblval][$field->Field] = $field;
				}
			}
		}
		return $result;
	}
	
	function isQuoted( $fieldName )
	{
		if ($this->_hasQuoted) {
			return in_array( $fieldName, $this->_quoted );
		} else {
			return true;
		}
	}
	
	function addQuoted( $quoted )
	{
		if (is_string( $quoted )) {
			$this->_quoted[] = $quoted;
		} else {
			$this->_quoted = array_merge( $this->_quoted, (array)$quoted );
		}
		$this->_hasQuoted = true;
	}
	
	//引用符合
	function Quote( $text, $escaped = true )
	{
		return '\''.($escaped ? $this->getEscaped( $text ) : $text).'\'';
	}
	//转义 SQL 语句中使用的字符串中的特殊字符
	function getEscaped( $text, $extra = false )
	{
		$result = mysql_real_escape_string( $text, $this->_resource );
		if ($extra) {
			$result = addcslashes( $result, '%_' );
		}
		return $result;
	}
	//表的引用符合 `
	function nameQuote( $s )
	{
		if (strpos( '.', $s ) === false)
		{
			$q = $this->_nameQuote;
			if (strlen( $q ) == 1) {
				return $q . $s . $q;
			} else {
				return $q{0} . $s . $q{1};
			}
		}
		else {
			return $s;
		}
	}
}
# 本程序是一个开源系统,使用时请你仔细阅读使用协议,商业用途请自觉购买商业授权.
# Copyright (C) 长沙米拓信息技术有限公司 (http://www.metinfo.cn). All rights reserved.
?>
